#ifndef LIST_H
#define LIST_H

#include "comm/types.h"

typedef struct _list_node_t {
    struct _list_node_t *pre;
    struct _list_node_t *next;
} list_node_t;

typedef struct _list_t {
    list_node_t *first;
    list_node_t *last;
    uint32_t count;
} list_t;

static inline void list_node_init(list_node_t *node)
{
    node->pre = node->next = NULL;
}

static inline list_node_t * list_node_pre(list_node_t *node)
{
    return node->pre;
}

static inline list_node_t * list_node_next(list_node_t *node)
{
    return node->next;
}

static inline _Bool list_is_empty(list_t *list)
{
    return list->count == 0;
}

static inline uint32_t list_count(list_t *list)
{
    return list->count;
}

static inline list_node_t * list_first(list_t *list)
{
    return list->first;
}

static inline list_node_t * list_last(list_t *list)
{
    return list->last;
}

/**
 * 求某字段在结构体中的偏移量
 */
#define offset_in_struct(struct_type, field) \
    ((uint32_t)&((struct_type *)0)->field)

/**
 * 求某字段所在结构体的地址值
 */
#define struct_addr(field_addr, struct_type, field) \
    ((uint32_t)field_addr - offset_in_struct(struct_type, field))

/**
 * 求某字段所在结构体的地址
 */
#define field_struct_addr(field_addr, struct_type, field) \
    ((struct_type *)(field_addr ? struct_addr(field_addr, struct_type, field) : 0))

void list_init(list_t *list);
void list_insert_first(list_t *list, list_node_t *node);
void list_insert_last(list_t *list, list_node_t *node);
list_node_t * list_remove_first(list_t *list);
list_node_t * list_remove_last(list_t *list);
list_node_t * list_remove(list_t *list, list_node_t *remove_node);

#endif  // LIST_H
